package com.wx.cloud.user.service.impl;

import com.wx.cloud.user.common.CommonResult;
import com.wx.cloud.user.common.JwtTokenUtil;
import com.wx.cloud.user.mapper.RoleMapper;
import com.wx.cloud.user.mapper.UserMapper;
import com.wx.cloud.user.model.Permission;
import com.wx.cloud.user.model.User;
import com.wx.cloud.user.model.UserRole;
import com.wx.cloud.user.service.RedisService;
import com.wx.cloud.user.service.UserService;
import com.wx.cloud.user.utils.MyDate;
import com.wx.cloud.user.vo.LoginParam;
import org.apache.commons.lang.StringUtils;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("userService")
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private RedisService redisService;

    @Autowired
    TopicExchange registerTopicExchange;
    @Autowired
    private RabbitTemplate template;

    @RabbitListener(queues = {"springboot.rabbit"})
    public void get(User user) {
        if (user != null){
            System.out.println("开始注册");
        }
    }

    @Override
    @Transactional
    public String register(User user) {
        template.convertAndSend(registerTopicExchange.getName(),"qw.queue", user);
        get(user);
        // 验证账号
        List<User> users = userMapper.getUserByUserCode(user.getUserCode());
        if (users.size() == 0){
            String password = passwordEncoder.encode(user.getPassword());
            user.setPassword(password);
            user.setCreateTime(MyDate.getDate());
            user.setUpdateTime(MyDate.getDate());
            int result = userMapper.saveUser(user);
            if (result > 0){
                UserRole userRole = new UserRole();
                userRole.setUserCode(user.getUserCode());
                userRole.setRoleId(2);
                userMapper.saveUserRole(userRole);
                return "success";
            }
           return "false";
        }else{
            return "repeat";
        }
    }

    @Override
    public String login(LoginParam loginParam, HttpServletRequest request) {
        String username = loginParam.getUserCode();
        Assert.notNull(username, "账号必须不为空");
        String password = loginParam.getPassword();
        Assert.notNull(password, "密码必须不为空");
        User userByUserCode = getUserByUserCode(username);
        String state = userByUserCode.getStateCode();
        UserRole ur = userMapper.getUserByUserRole(username);
        if (!ur.getRoleState().equals("disable")){
            if (!state.equals("frozen")) {
                boolean matches = passwordEncoder.matches(password, userByUserCode.getPassword());
                if (matches) {
                    redisService.del("frozenCount:" + username);
                    return jwtTokenUtil.generateToken(userByUserCode);
                } else {
                    return judge(username);
                }
            }
            return "该用户已被冻结";
        }
        return "该用户的角色已被禁用";
    }

    private String judge(String username) {
        int frozenCount = 1;
        boolean frozenFlag = true;
        if (!redisService.hasKey("frozenFlag:" + username)){
            if (!redisService.hasKey("frozenCount:" + username)) {
                redisService.set("frozenCount:" + username, frozenCount, 60 * 60);
            } else {
                frozenCount = (int) redisService.get("frozenCount:" + username) + 1;
                redisService.set("frozenCount:" + username, frozenCount, 60 * 60);
                if (frozenCount >= 3) {
                    redisService.set("frozenFlag:" + username, frozenFlag, 60 * 60 * 24);
                    return "密码输入错误超过三次，该用户已被冻结";
                }
            }
            return "用户名或密码错误";
        }
        return "该用户已被冻结";
    }

    @Override
    public int perfect(User user) {
        user.setUpdateTime(MyDate.getDate());
        return userMapper.updateUser(user);
    }

    @Override
    public User findUserByUserCode(String userCode) {
        return userMapper.findUserByUserCode(userCode);
    }

    @Override
    public User getUserByUserCode(String username) {
        List<User> users= userMapper.getUserByUserCode(username);
        Assert.isTrue(users.size()==1,"您输入的账户不存在，或者有多个相同的账户");
        return users.get(0);
    }

    @Override
    public List<Permission> getPermissionsByUserId(String userCode) {
        return userMapper.getPermissionsByUserId(userCode);
    }

    @Override
    public List<User> getUserList(Map<String, Object> data) {
        int page = Integer.parseInt((String)data.get("pageNum"));
        int size = Integer.parseInt((String)data.get("pageSize"));
        data.put("pageNum",(page-1)*size);
        data.put("pageSize",size);
        return userMapper.getUserList(data);
    }

    @Override
    public int getSelectCount(Map<String, Object> data) {
        return userMapper.getSelectCount(data);
    }

    @Override
    public int updateState(User user) {
        user.setUpdateTime(MyDate.getDate());
        return userMapper.updateState(user);
    }

    @Override
    @Transactional
    public int updateUser(Map<String, Object> data) {
        User user = new User();
        user.setUserCode((String)data.get("userCode"));
        user.setName((String)data.get("name"));
        user.setSexCode((String)data.get("sexCode"));
        user.setEducation((String)data.get("education"));
        user.setAddress((String)data.get("address"));
        user.setPhone((String)data.get("phone"));
        user.setUpdateTime(MyDate.getDate());
        int result = userMapper.updateUser(user);
        if (result > 0){
            UserRole userRole = new UserRole();
            String userCode = (String)data.get("userCode");
            userRole.setUserCode(userCode);
            int roleId = Integer.parseInt((String)data.get("roleId"));
            userRole.setRoleId(roleId);
            UserRole ur = userMapper.getUserByUserRole(userCode);
            if(ur == null){
                userMapper.saveUserRole(userRole);
            } else{
                userMapper.updateUserRole(userRole);
            }
            changeRoleCount(roleId);
        }
        return result;
    }

    private int changeRoleCount(int roleId) {
        int count = roleMapper.getCountByRole(roleId);
        Map param = new HashMap();
        param.put("userCount",count);
        param.put("id",roleId);
        param.put("updateTime", MyDate.getDate());
        return roleMapper.updateRoleCount(param);
    }

    @Override
    public int delUser(User user) {
        user.setUpdateTime(MyDate.getDate());
        return userMapper.delUser(user);
    }

    @Override
    public CommonResult checkAccessToUri(String uri, String username) {
        List<Permission> permissionsByUserId = getPermissionsByUserId(username);
        boolean b = permissionsByUserId.stream().anyMatch(permission -> StringUtils.equals(permission.getUri(), uri));
        return b?CommonResult.success(true):CommonResult.failed();
    }
}
